/*
 * jxSwing Project (2014)
 * 
 * by Denilson Edinaldo Pinto
 * 
 * LGPL
 * Copyright (C) 2014
 * 
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */
package org.jxSwing.component.table;

import java.io.Serializable;
import java.lang.reflect.Method;

import org.jxSwing.component.table.annotation.Column;
import org.jxUtils.TypeUtil;

/**
 * @author Denilson Edinaldo Pinto
 * @porject jxSwing
 * @package org.jxSwing.component.table
 * @date 27/01/2014 - 20:07:05
 */
public final class BeanTableColumn implements Serializable, Comparable<BeanTableColumn> {
	
	private static final long serialVersionUID = -7927072693311191498L;
	
	private Integer index;
	
	private boolean visible;
	
	private String mask;
	
	private boolean money;
	
	private int decimalDigits;
	
	private String alias;
	
	private boolean editable;
	
	private boolean indicatesPercentage;
	
	private final String name;
	
	private final Class<?> type;
	
	private Method beanMethodGet;
	
	private Method beanMethodSet;
	
	/**
	 * @param name
	 */
	BeanTableColumn(final String name) {
	
		this(name, String.class, null);
	}
	
	/**
	 * 
	 */
	public BeanTableColumn() {
	
		this("A", true, String.class, null);
	}
	
	/**
	 * @param annotation
	 * @param name
	 * @param alias
	 * @param editable
	 * @param type
	 * @param beanMethodGet
	 */
	public BeanTableColumn(final Column annotation, final String name, final String alias, final boolean editable, final Class<?> type, final Method beanMethodGet) {
	
		this.name = name;
		this.alias = alias;
		this.editable = editable;
		this.type = type;
		this.index = -1;
		this.visible = true;
		this.mask = "";
		this.money = false;
		this.decimalDigits = 0;
		this.beanMethodGet = beanMethodGet;
		
		//
		if(annotation != null) {
			
			index = annotation.index();
			visible = annotation.visible();
			mask = annotation.mask();
			indicatesPercentage = annotation.indicatesPercentage();
			
			//
			if(TypeUtil.isRealNumber(type)) {
				
				money = annotation.money();
				decimalDigits = annotation.decimalDigits();
			}
		}
	}
	
	/**
	 * @param annotation
	 * @param name
	 * @param alias
	 * @param type
	 * @param beanMethodGet
	 */
	public BeanTableColumn(final Column annotation, final String name, final String alias, final Class<?> type, final Method beanMethodGet) {
	
		this(annotation, name, alias, true, type, beanMethodGet);
	}
	
	/**
	 * @param index
	 * @param name
	 * @param alias
	 * @param editable
	 * @param type
	 * @param visible
	 * @param mask
	 * @param decimalDigits
	 * @param money
	 * @param beanMethodGet
	 */
	public BeanTableColumn(final int index, final String name, final String alias, final boolean editable, final Class<?> type, final boolean visible, final String mask, final boolean money, final int decimalDigits, final Method beanMethodGet) {
	
		this.index = index;
		this.name = name;
		this.alias = alias;
		this.editable = editable;
		this.type = type;
		this.visible = visible;
		this.mask = mask;
		this.money = money;
		this.decimalDigits = decimalDigits;
		this.beanMethodGet = beanMethodGet;
	}
	
	/**
	 * @param name
	 * @param editable
	 * @param type
	 * @param beanMethodGet
	 */
	public BeanTableColumn(final String name, final boolean editable, final Class<?> type, final Method beanMethodGet) {
	
		this(null, name, name, editable, type, beanMethodGet);
	}
	
	/**
	 * @param name
	 * @param type
	 * @param beanMethodGet
	 */
	public BeanTableColumn(final String name, final Class<?> type, final Method beanMethodGet) {
	
		this(name, true, type, beanMethodGet);
	}
	
	/**
	 * @param name
	 * @param alias
	 * @param type
	 */
	public BeanTableColumn(final String name, final String alias, final Class<?> type) {
	
		this(null, name, alias, true, type, null);
	}
	
	/*
	 * (non-Javadoc)
	 * 
	 * @see java.lang.Comparable#compareTo(java.lang.Object)
	 */
	@Override
	public int compareTo(final BeanTableColumn beanTableColumn) {
	
		return getIndex().compareTo(beanTableColumn.getIndex());
	}
	
	/*
	 * (non-Javadoc)
	 * 
	 * @see java.lang.Object#equals(java.lang.Object)
	 */
	@Override
	public boolean equals(final Object obj) {
	
		if(this == obj) {
			return true;
		}
		if(obj == null) {
			return false;
		}
		if( !(obj instanceof BeanTableColumn)) {
			return false;
		}
		final BeanTableColumn other = (BeanTableColumn)obj;
		if(alias == null) {
			if(other.alias != null) {
				return false;
			}
		}else if( !alias.equals(other.alias)) {
			return false;
		}
		if(name == null) {
			if(other.name != null) {
				return false;
			}
		}else if( !name.equals(other.name)) {
			return false;
		}
		return true;
	}
	
	/**
	 * @return the alias
	 */
	public String getAlias() {
	
		return alias;
	}
	
	/**
	 * @return the beanMethodGet
	 */
	public Method getBeanMethodGet() {
	
		return beanMethodGet;
	}
	
	/**
	 * @return the beanMethodSet
	 */
	public Method getBeanMethodSet() {
	
		return beanMethodSet;
	}
	
	/**
	 * @return the decimalDigits
	 */
	public int getDecimalDigits() {
	
		return decimalDigits;
	}
	
	/**
	 * @return the index
	 */
	public Integer getIndex() {
	
		return index;
	}
	
	/**
	 * @return the mask
	 */
	public String getMask() {
	
		return mask;
	}
	
	/**
	 * @return the name
	 */
	public String getName() {
	
		return name;
	}
	
	/**
	 * @return the type
	 */
	public Class<?> getType() {
	
		return type;
	}
	
	/*
	 * (non-Javadoc)
	 * 
	 * @see java.lang.Object#hashCode()
	 */
	@Override
	public int hashCode() {
	
		final int prime = 31;
		int result = 1;
		result = prime * result + (alias == null ? 0 : alias.hashCode());
		result = prime * result + (name == null ? 0 : name.hashCode());
		return result;
	}
	
	/**
	 * @return the editable
	 */
	public boolean isEditable() {
	
		return editable;
	}
	
	/**
	 * @return the indicatesPercentage
	 */
	public boolean isIndicatesPercentage() {
	
		return indicatesPercentage;
	}
	
	/**
	 * @return the money
	 */
	public boolean isMoney() {
	
		return money;
	}
	
	/**
	 * @return the visible
	 */
	public boolean isVisible() {
	
		return visible;
	}
	
	/**
	 * @param alias
	 *        the alias to set
	 */
	public void setAlias(final String alias) {
	
		this.alias = alias;
	}
	
	/**
	 * @param beanMethodGet
	 */
	public void setBeanMethodGet(final Method beanMethodGet) {
	
		this.beanMethodGet = beanMethodGet;
	}
	
	/**
	 * @param beanMethodSet
	 */
	public void setBeanMethodSet(final Method beanMethodSet) {
	
		this.beanMethodSet = beanMethodSet;
	}
	
	/**
	 * @param decimalDigits
	 *        the decimalDigits to set
	 */
	public void setDecimalDigits(final int decimalDigits) {
	
		this.decimalDigits = decimalDigits;
	}
	
	/**
	 * @param editable
	 *        the editable to set
	 */
	public void setEditable(final boolean editable) {
	
		this.editable = editable;
	}
	
	/**
	 * @param index
	 *        the index to set
	 */
	public void setIndex(final Integer index) {
	
		this.index = index;
	}
	
	/**
	 * @param indicatesPercentage
	 *        the indicatesPercentage to set
	 */
	public void setIndicatesPercentage(final boolean indicatesPercentage) {
	
		this.indicatesPercentage = indicatesPercentage;
	}
	
	/**
	 * @param mask
	 *        the mask to set
	 */
	public void setMask(final String mask) {
	
		this.mask = mask;
	}
	
	/**
	 * @param money
	 *        the money to set
	 */
	public void setMoney(final boolean money) {
	
		this.money = money;
	}
	
	/**
	 * @param visible
	 *        the visible to set
	 */
	public void setVisible(final boolean visible) {
	
		this.visible = visible;
	}
	
	/*
	 * (non-Javadoc)
	 * 
	 * @see java.lang.Object#toString()
	 */
	@Override
	public String toString() {
	
		return alias;
	}
}
